package com.mspbots.api.service.impl;

import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.mspbots.api.config.ApiProperties;
import com.mspbots.api.service.MessagesService;
import com.mspbots.cw.request.MessagesDTO;
import com.mspbots.cw.request.TriggerEscalationDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import reactor.core.publisher.Mono;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Future;

/**
 * com.mspbots.api.service.impl.MessagesServiceImpl
 *
 * @author Jun Zhou
 * @date 16:09 2019/6/28
 **/
@Deprecated
@Slf4j
@Service
public class MessagesServiceImpl extends BaseGenericService implements MessagesService {

    @Autowired
    private ApiProperties apiProperties;

    @Override
    public MessagesDTO insert(MessagesDTO messages) {
//        if (!check(messages)) {
        Mono<JsonNode> resultMono = this.apiClient.post("/teams/messages/", messages);
        JsonNode result = resultMono.block();
        return this.objectMapper.convertValue(result, MessagesDTO.class);
//        }


//        return null;
    }


    @Override
    public List<MessagesDTO> findByTimeEntryId(Long entryId) {
        Mono<JsonNode> resultMono = this.apiClient.get("/teams/messages/list/by-entry/" + entryId);
        JsonNode result = resultMono.block();
        return this.objectMapper.convertValue(result, new TypeReference<List<MessagesDTO>>() {
        });
    }


    @Override
    public List<MessagesDTO> findList(Map<String, Object> params) {
        Mono<JsonNode> resultMono = this.apiClient.get("/teams/messages/list/send", params);
        JsonNode result = resultMono.block();
        return this.objectMapper.convertValue(result, new TypeReference<List<MessagesDTO>>() {
        });
    }

    @Async
    @Override
    public Future<String> sendToTeams(MessagesDTO messages, String type) {
        HashMap<String, Object> params = new HashMap<>(16);

//            params.put("userid", "0a787f48-cf48-46a5-b63b-3e1ebe8faa57");
//            params.put("message", messages.getMessage() + "test by zj");
        params.put("message", messages.getMessage());
        params.put("userid", messages.getTeamsUserId());
        try {
            if (!StringUtils.isEmpty(messages.getTeamsUserId())) {
                String result = HttpUtil.post(apiProperties.getTeamsApiUrl() + "/notify", params);
                JSONObject jsonObject = JSONUtil.parseObj(result);
                log.info("send msg {} to {} {} [{}]", messages.getId(), messages.getTeamsUserId(), jsonObject.getStr("errorcode"), type);
                return new AsyncResult<String>(jsonObject.getStr("errorcode"));
            } else {
                log.error("msg {} has no teams_user_id ", messages.getId());
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return new AsyncResult<String>("0");
    }


    @Override
    public void updateStatus(MessagesDTO messages) {
        Map<String, Object> params = new HashMap<>(16);
        params.put("id", messages.getId());
        if (!StringUtils.isEmpty(messages.getStatus())) {
            params.put("status", messages.getStatus());
            params.put("sentTime", LocalDateTime.now());
        }
        if (!StringUtils.isEmpty(messages.getForwardStatus())) {
            params.put("forwardStatus", messages.getForwardStatus());
        }

        Mono<JsonNode> resultMono = this.apiClient.put("/teams/messages/" + messages.getId(), params);
        resultMono.block();
    }

    @Override
    public void batchUpdateStatus(List<MessagesDTO> messagesDTOList) {
        try {
            Mono<JsonNode> resultMono = this.apiClient.put("/teams/messages/updateBatch", messagesDTOList);
            resultMono.block();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }


    @Override
    public boolean check(MessagesDTO messages) {
        try {
            Map<String, Object> queryParams = new HashMap<>(16) {{
                put("ruleId", messages.getRuleId());
                put("tenantId", messages.getTenantId());
                put("timeEntryId", messages.getTimeEntryId());
                put("tsheetTimesId", messages.getTsheetTimesId());
                put("createDate", messages.getCreateDate());
                put("userId", messages.getUserId());
                put("businessId", messages.getBusinessId());
            }};

            Mono<JsonNode> resultMono = this.apiClient.get("/teams/messages/countMessagesByForRule", queryParams);
            JsonNode result = resultMono.block();

            return this.objectMapper.convertValue(result, Integer.class) > 0;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;

    }

    @Override
    public boolean checkEscalation(MessagesDTO messages) {
        try {
            Map<String, Object> queryParams = new HashMap<>(16) {{
                put("ruleId", messages.getRuleId());
                put("escalation", messages.getEscalation());
                put("tenantId", messages.getTenantId());
                put("createDate", messages.getCreateDate());
                put("userId", messages.getUserId());
                put("businessType", messages.getBusinessType());
            }};

            Mono<JsonNode> resultMono = this.apiClient.get("/teams/messages/countEscalation", queryParams);
            JsonNode result = resultMono.block();

            return this.objectMapper.convertValue(result, Integer.class) > 0;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;

    }

    @Override
    public List<TriggerEscalationDTO> triggerEscalationList(Map<String, Object> params) {
        Mono<JsonNode> resultMono = this.apiClient.get("/teams/messages/triggerEscalationList", params);
        JsonNode result = resultMono.block();

        return this.objectMapper.convertValue(result, new TypeReference<List<TriggerEscalationDTO>>() {
        });
    }

    @Override
    public int getRuleCount(Map<String, Object> params) {
        Mono<JsonNode> resultMono = this.apiClient.get("/teams/messages/countEscalation", params);
        JsonNode result = resultMono.block();

        return this.objectMapper.convertValue(result, Integer.class);
    }


}
